import json
import uuid
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib import messages
from django.http import HttpResponseForbidden, JsonResponse, HttpResponseNotAllowed
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext_lazy as _
from django.db.models import Q
from django.core.paginator import Paginator
from django.views.decorators.http import require_http_methods
from django.urls import reverse
from .models import Project, ProjectMember, ProjectTag, Webhook, Announcement, Message, MessageNote, MessageProcessingHistory
from .forms import ProjectForm, ProjectMemberForm, ProjectTagForm, WebhookForm, AnnouncementForm
from accounts.models import User
# 导入webhook触发函数
from .webhook_service import (
    trigger_project_created,
    trigger_project_updated,
    trigger_project_deleted,
    trigger_member_added,
    trigger_member_removed,
    trigger_member_role_changed,
    trigger_tag_added,
    trigger_tag_deleted,
    trigger_announcement_sent
)

@login_required
def dashboard(request):
    """用户仪表盘视图 - 集中展示所有项目消息"""
    # 超级管理员可以看到所有项目，普通用户只能看到自己参与的项目
    if request.user.is_super_admin():
        user_projects = Project.objects.all().order_by('-created_at')
    else:
        user_projects = Project.objects.filter(members__user=request.user).order_by('-created_at')
    
    # 获取用户在所有项目中的消息
    from django.utils import timezone
    from datetime import timedelta
    
    today = timezone.now().date()
    tomorrow = today + timedelta(days=1)
    
    # 获取所有相关项目ID
    project_ids = user_projects.values_list('id', flat=True)
    
    # 获取所有消息（包括项目消息和公共公告）
    user_messages = Message.objects.filter(
        project__in=project_ids
    ).select_related('project').order_by('-created_at')
    
    # 获取公告（公共消息）
    announcements = Announcement.objects.filter(
        is_active=True
    ).order_by('-created_at')
    
    # 统计信息
    total_messages = user_messages.count()
    pending_messages = user_messages.filter(status='pending').count()
    processed_messages = user_messages.filter(status='processed').count()
    today_messages = user_messages.filter(created_at__gte=today, created_at__lt=tomorrow).count()
    
    # 获取用户角色信息
    project_roles = {}
    for project in user_projects:
        # 对于超级管理员，所有项目都拥有管理员权限
        if request.user.is_super_admin():
            project_roles[project.id] = 'admin'
        else:
            try:
                member = project.members.get(user=request.user)
                project_roles[project.id] = member.role
            except ProjectMember.DoesNotExist:
                project_roles[project.id] = 'viewer'
    
    # 分页处理
    paginator = Paginator(user_messages, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'user_projects': user_projects,
        'user_messages': page_obj,
        'announcements': announcements,
        'stats': {
            'total_messages': total_messages,
            'pending_messages': pending_messages,
            'processed_messages': processed_messages,
            'today_messages': today_messages,
            'total_projects': user_projects.count()
        },
        'project_roles': project_roles,
        'page_obj': page_obj,
        'is_super_admin': request.user.is_super_admin()
    }

    return render(request, 'projects/dashboard.html', context)

@login_required
def project_list(request):
    """项目列表视图"""
    # 超级管理员可以看到所有项目，普通用户只能看到自己参与的项目
    if request.user.is_super_admin():
        projects = Project.objects.all().order_by('-created_at')
    else:
        projects = Project.objects.filter(members__user=request.user).order_by('-created_at')
    
    return render(request, 'projects/project_list.html', {'projects': projects})

@login_required
def project_create(request):
    """创建新项目视图"""
    if request.method == 'POST':
        form = ProjectForm(request.POST)
        if form.is_valid():
            # 创建项目，但还不保存到数据库
            project = form.save(commit=False)
            # 设置创建者为当前用户
            project.created_by = request.user
            # 保存项目
            project.save()
            # 创建项目成员记录，将创建者设置为管理员
            ProjectMember.objects.create(
                project=project,
                user=request.user,
                role='admin'
            )
            
            # 自动为新项目生成Webhook
            import uuid
            from django.conf import settings
            # 使用项目ID作为webhook URL的一部分
            project_id_str = str(project.id)
            
            # 创建Webhook对象，使用临时URL
            temp_url = f"{settings.SITE_DOMAIN}/webhooks/temp-url"
            webhook = Webhook.objects.create(
                project=project,
                name=f"{project.name} - 自动生成Webhook",
                url=temp_url,  # 使用临时URL
                # 只绑定报警信息类事件
                events=['alarm'],
                is_active=True
            )
            
            # 获取实际生成的Webhook ID
            actual_webhook_id = str(webhook.id)
            print(f"实际生成的Webhook ID: {actual_webhook_id}")
            
            # 使用实际的Webhook ID生成正确的URL
            base_url = settings.SITE_DOMAIN
            correct_webhook_url = f"{base_url}/webhooks/{project_id_str}/{actual_webhook_id}/receive/"
            print(f"生成的正确Webhook URL: {correct_webhook_url}")
            
            # 更新Webhook的URL
            webhook.url = correct_webhook_url
            webhook.save()
            
            # 额外输出信息，方便调试
            print(f"Webhook创建成功:\n- 项目ID: {project_id_str}\n- Webhook ID: {actual_webhook_id}\n- URL: {correct_webhook_url}")
            
            messages.success(request, _('项目创建成功，并自动生成了Webhook！'))
            
            # 触发项目创建webhook
            trigger_project_created(project)
            
            return redirect('projects:project_detail', project_id=project.id)
    else:
        form = ProjectForm()
        
    return render(request, 'projects/project_form.html', {'form': form, 'title': _('创建项目')})

@login_required
def project_detail(request, project_id):
    """项目详情视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 检查用户是否有权限访问该项目
    # 超级管理员可以访问所有项目，无需成为项目成员
    if not request.user.is_super_admin() and not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    # 获取当前用户在项目中的角色
    # 对于超级管理员，设置为最高权限角色
    if request.user.is_super_admin():
        user_role = 'admin'
    else:
        user_role = project.members.get(user=request.user).role
    
    # 获取项目成员和标签
    members = project.members.all()
    tags = project.tags.all()
    
    # 获取与该项目相关的公告
    # 公告要么没有标签（全局公告），要么包含该项目的标签
    project_tag_ids = tags.values_list('id', flat=True)
    announcements = Announcement.objects.filter(
        is_active=True
    ).filter(
        Q(tags__isnull=True) | Q(tags__id__in=project_tag_ids)
    ).distinct().order_by('-created_at')
    
    # 获取消息统计信息
    from django.utils import timezone
    from datetime import timedelta
    
    today = timezone.now().date()
    tomorrow = today + timedelta(days=1)
    
    messages = Message.objects.filter(project=project)
    message_count = messages.count()
    pending_count = messages.filter(status='pending').count()
    processed_count = messages.filter(status='processed').count()
    today_count = messages.filter(created_at__gte=today, created_at__lt=tomorrow).count()
    
    # 获取最近的消息（最多5条）
    recent_messages = messages.order_by('-created_at')[:5]
    
    return render(request, 'projects/project_detail.html', {
        'project': project,
        'members': members,
        'tags': tags,
        'user_role': user_role,
        'announcements': announcements,
        'message_count': message_count,
        'message_stats': {
            'total_count': message_count,
            'pending_count': pending_count,
            'processed_count': processed_count,
            'today_count': today_count,
            'recent': recent_messages
        }
    })

@login_required
def project_update(request, project_id):
    """更新项目视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以更新所有项目
    if request.user.is_super_admin():
        # 超级管理员有全部权限
        pass
    else:
        # 检查用户是否有权限更新该项目
        try:
            member = project.members.get(user=request.user)
            # 只有管理员和程序员才能更新项目
            if member.role not in ['admin', 'developer']:
                return HttpResponseForbidden(_('您没有权限更新此项目。'))
        except ProjectMember.DoesNotExist:
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        form = ProjectForm(request.POST, instance=project)
        if form.is_valid():
            # 获取更新前的项目数据，以便确定哪些字段被更新了
            updated_fields = []
            for field in form.changed_data:
                updated_fields.append(field)
            
            form.save()
            messages.success(request, _('项目更新成功！'))
            
            # 触发项目更新webhook
            trigger_project_updated(project, updated_fields)
            
            return redirect('projects:project_detail', project_id=project.id)
    else:
        form = ProjectForm(instance=project)
        
    return render(request, 'projects/project_form.html', {
        'form': form,
        'title': _('更新项目'),
        'project': project
    })

@login_required
def project_delete(request, project_id):
    """删除项目视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以删除所有项目
    if request.user.is_super_admin():
        # 超级管理员有全部权限
        pass
    else:
        # 检查用户是否有权限删除该项目
        try:
            member = project.members.get(user=request.user)
            # 只有管理员才能删除项目
            if member.role != 'admin':
                return HttpResponseForbidden(_('您没有权限删除此项目。'))
        except ProjectMember.DoesNotExist:
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        # 保存项目名称，因为删除后无法访问
        project_name = project.name
        project_id = project.id
        
        # 在删除前触发项目删除webhook
        trigger_project_deleted(project_id, project_name)
        
        project.delete()
        messages.success(request, _('项目删除成功！'))
        return redirect('projects:project_list')
        
    return render(request, 'projects/project_confirm_delete.html', {'project': project})

@login_required
def project_members(request, project_id):
    """项目成员列表视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以访问所有项目的成员列表
    if request.user.is_super_admin():
        # 超级管理员有全部权限
        user_role = 'admin'  # 为超级管理员设置最高权限角色
    else:
        # 检查用户是否有权限访问项目成员列表
        if not project.members.filter(user=request.user).exists():
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
        # 获取当前用户在项目中的角色
        user_role = project.members.get(user=request.user).role
    
    # 获取项目成员
    members = project.members.all()
    
    return render(request, 'projects/project_members.html', {
        'project': project,
        'members': members,
        'user_role': user_role
    })

@login_required
def project_add_member(request, project_id):
    """添加项目成员视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以为所有项目添加成员
    if request.user.is_super_admin():
        # 超级管理员有全部权限
        pass
    else:
        # 检查用户是否有权限添加项目成员
        try:
            member = project.members.get(user=request.user)
            # 只有管理员才能添加项目成员
            if member.role != 'admin':
                return HttpResponseForbidden(_('您没有权限添加项目成员。'))
        except ProjectMember.DoesNotExist:
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        form = ProjectMemberForm(request.POST)
        if form.is_valid():
            # 检查用户是否已在项目中
            user = form.cleaned_data['user']
            if project.members.filter(user=user).exists():
                messages.error(request, _('该用户已经是项目成员。'))
            else:
                # 创建项目成员记录
                ProjectMember.objects.create(
                    project=project,
                    user=user,
                    role=form.cleaned_data['role']
                )
                # 触发添加成员webhook
                trigger_member_added(project, user, form.cleaned_data['role'])
                
                messages.success(request, _('项目成员添加成功！'))
                return redirect('projects:project_members', project_id=project.id)
    else:
        form = ProjectMemberForm()
        
    return render(request, 'projects/project_member_form.html', {
        'form': form,
        'title': _('添加项目成员'),
        'project': project
    })

@login_required
def project_remove_member(request, project_id, member_id):
    """移除项目成员视图"""
    project = get_object_or_404(Project, id=project_id)
    member_to_remove = get_object_or_404(ProjectMember, id=member_id, project=project)
    
    # 超级管理员可以移除所有项目的成员（但不能移除自己）
    if request.user.is_super_admin():
        # 超级管理员不能移除自己
        if request.user.id == member_to_remove.user.id:
            return HttpResponseForbidden(_('您不能移除自己。'))
    else:
        # 检查用户是否有权限移除项目成员
        try:
            current_member = project.members.get(user=request.user)
            # 只有管理员才能移除项目成员，且不能移除自己
            if current_member.role != 'admin' or current_member.id == member_to_remove.id:
                return HttpResponseForbidden(_('您没有权限移除该项目成员。'))
        except ProjectMember.DoesNotExist:
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        # 保存成员信息，因为删除后无法访问
        user = member_to_remove.user
        role = member_to_remove.role
        
        member_to_remove.delete()
        
        # 触发移除成员webhook
        trigger_member_removed(project, user, role)
        
        messages.success(request, _('项目成员移除成功！'))
        return redirect('projects:project_members', project_id=project.id)
        
    return render(request, 'projects/project_member_confirm_remove.html', {
        'project': project,
        'member_to_remove': member_to_remove
    })

@login_required
def project_update_member(request, project_id, member_id):
    """更新项目成员角色视图"""
    project = get_object_or_404(Project, id=project_id)
    member_to_update = get_object_or_404(ProjectMember, id=member_id, project=project)
    
    # 超级管理员可以更新所有项目成员的角色（但不能更新自己的角色）
    if request.user.is_super_admin():
        # 超级管理员不能更新自己的角色
        if request.user.id == member_to_update.user.id:
            return HttpResponseForbidden(_('您不能更新自己的角色。'))
    else:
        # 检查用户是否有权限更新项目成员角色
        try:
            current_member = project.members.get(user=request.user)
            # 只有管理员才能更新项目成员角色，且不能更新自己的角色
            if current_member.role != 'admin' or current_member.id == member_to_update.id:
                return HttpResponseForbidden(_('您没有权限更新该项目成员角色。'))
        except ProjectMember.DoesNotExist:
            return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        form = ProjectMemberForm(request.POST, instance=member_to_update)
        if form.is_valid():
            # 保存旧的角色值
            old_role = member_to_update.role
            new_role = form.cleaned_data['role']
            
            form.save()
            
            # 只有当角色确实改变时才触发webhook
            if old_role != new_role:
                trigger_member_role_changed(project, member_to_update.user, old_role, new_role)
            
            messages.success(request, _('项目成员角色更新成功！'))
            return redirect('projects:project_members', project_id=project.id)
    else:
        form = ProjectMemberForm(instance=member_to_update)
        # 禁用用户选择字段
        form.fields['user'].disabled = True
        
    return render(request, 'projects/project_member_form.html', {
        'form': form,
        'title': _('更新项目成员角色'),
        'project': project,
        'member_to_update': member_to_update
    })

@login_required
def project_tags(request, project_id):
    """项目标签列表视图"""
    project = get_object_or_404(Project, id=project_id)
    # 检查用户是否有权限访问项目标签列表
    if not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    # 获取当前用户在项目中的角色
    user_role = project.members.get(user=request.user).role
    
    # 获取项目标签
    tags = project.tags.all()
    
    return render(request, 'projects/project_tags.html', {
        'project': project,
        'tags': tags,
        'user_role': user_role
    })

@login_required
def project_add_tag(request, project_id):
    """添加项目标签视图"""
    project = get_object_or_404(Project, id=project_id)
    # 检查用户是否有权限添加项目标签
    try:
        member = project.members.get(user=request.user)
        # 只有管理员和程序员才能添加项目标签
        if member.role not in ['admin', 'developer']:
            return HttpResponseForbidden(_('您没有权限添加项目标签。'))
    except ProjectMember.DoesNotExist:
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        form = ProjectTagForm(request.POST)
        if form.is_valid():
            # 检查标签是否已存在
            tag_name = form.cleaned_data['name']
            if project.tags.filter(name=tag_name).exists():
                messages.error(request, _('该标签已经存在。'))
            else:
                # 创建项目标签
                tag = ProjectTag.objects.create(
                    project=project,
                    name=tag_name,
                    color=form.cleaned_data['color']
                )
                
                # 触发添加标签webhook
                trigger_tag_added(project, tag)
                
                messages.success(request, _('项目标签添加成功！'))
                return redirect('projects:project_tags', project_id=project.id)
    else:
        form = ProjectTagForm()
        
    return render(request, 'projects/project_tag_form.html', {
        'form': form,
        'title': _('添加项目标签'),
        'project': project
    })

@login_required
def project_delete_tag(request, project_id, tag_id):
    """删除项目标签视图"""
    project = get_object_or_404(Project, id=project_id)
    tag_to_delete = get_object_or_404(ProjectTag, id=tag_id, project=project)
    
    # 检查用户是否有权限删除项目标签
    try:
        member = project.members.get(user=request.user)
        # 只有管理员和程序员才能删除项目标签
        if member.role not in ['admin', 'developer']:
            return HttpResponseForbidden(_('您没有权限删除项目标签。'))
    except ProjectMember.DoesNotExist:
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
        
    if request.method == 'POST':
        # 保存标签信息，因为删除后无法访问
        tag_id = tag_to_delete.id
        tag_name = tag_to_delete.name
        
        # 触发删除标签webhook
        trigger_tag_deleted(project, tag_id, tag_name)
        
        tag_to_delete.delete()
        messages.success(request, _('项目标签删除成功！'))
        return redirect('projects:project_tags', project_id=project.id)
        
    return render(request, 'projects/project_tag_confirm_delete.html', {
        'project': project,
        'tag_to_delete': tag_to_delete
    })


@login_required
def project_webhooks(request, project_id):
    """项目Webhook列表视图"""
    project = get_object_or_404(Project, id=project_id)
    # 检查用户是否有权限访问此项目
    if not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))

    # 获取当前用户在项目中的角色
    user_role = project.members.get(user=request.user).role

    # 只有管理员才能管理webhook
    if user_role != 'admin':
        return HttpResponseForbidden(_('您没有权限管理项目的Webhook。'))

    # 获取项目的所有webhook
    webhooks = project.webhooks.all().order_by('-created_at')

    return render(request, 'projects/project_webhooks.html', {
        'project': project,
        'webhooks': webhooks,
        'user_role': user_role,
        'CHANNEL_CHOICES': Webhook.CHANNEL_CHOICES,
        'EVENT_CHOICES': Webhook.EVENT_CHOICES
    })


@login_required
def project_add_webhook(request, project_id):
    """添加项目Webhook视图"""
    project = get_object_or_404(Project, id=project_id)
    # 检查用户是否有权限访问此项目
    if not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取当前用户在项目中的角色
    user_role = project.members.get(user=request.user).role
    
    # 只有管理员才能添加webhook
    if user_role != 'admin':
        return HttpResponseForbidden(_('您没有权限添加项目的Webhook。'))
    
    if request.method == 'POST':
        form = WebhookForm(request.POST, project=project)
        if form.is_valid():
            form.save()
            messages.success(request, _('Webhook添加成功！'))
            return redirect('projects:project_webhooks', project_id=project.id)
    else:
        form = WebhookForm(project=project)
    
    return render(request, 'projects/project_webhook_form.html', {
        'form': form,
        'title': _('添加Webhook'),
        'project': project
    })


@login_required
def project_edit_webhook(request, project_id, webhook_id):
    """编辑项目Webhook视图"""
    project = get_object_or_404(Project, id=project_id)
    webhook = get_object_or_404(Webhook, id=webhook_id, project=project)
    
    # 检查用户是否有权限访问此项目
    if not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取当前用户在项目中的角色
    user_role = project.members.get(user=request.user).role
    
    # 只有管理员才能编辑webhook
    if user_role != 'admin':
        return HttpResponseForbidden(_('您没有权限编辑项目的Webhook。'))
    
    if request.method == 'POST':
        form = WebhookForm(request.POST, instance=webhook, project=project)
        if form.is_valid():
            form.save()
            messages.success(request, _('Webhook更新成功！'))
            return redirect('projects:project_webhooks', project_id=project.id)
    else:
        form = WebhookForm(instance=webhook, project=project)
    
    return render(request, 'projects/project_webhook_form.html', {
        'form': form,
        'title': _('编辑Webhook'),
        'project': project,
        'webhook': webhook
    })


@login_required
def project_delete_webhook(request, project_id, webhook_id):
    """删除项目Webhook视图"""
    project = get_object_or_404(Project, id=project_id)
    webhook = get_object_or_404(Webhook, id=webhook_id, project=project)
    
    # 检查用户是否有权限访问此项目
    if not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取当前用户在项目中的角色
    user_role = project.members.get(user=request.user).role
    
    # 只有管理员才能删除webhook
    if user_role != 'admin':
        return HttpResponseForbidden(_('您没有权限删除项目的Webhook。'))
    
    if request.method == 'POST':
        webhook.delete()
        messages.success(request, _('Webhook删除成功！'))
        return redirect('projects:project_webhooks', project_id=project.id)
    
    return render(request, 'projects/project_webhook_confirm_delete.html', {
        'project': project,
        'webhook': webhook
    })


from django.views.decorators.csrf import csrf_exempt


@csrf_exempt
def receive_webhook(request, project_slug, webhook_id):
    print(project_slug,webhook_id)
    """接收Webhook请求并将消息存储到项目中"""
    # 注意：这个视图不需要登录，因为它需要被外部服务调用
    # @csrf_exempt装饰器用于禁用CSRF保护，允许外部服务调用

    # 首先根据webhook_id查找对应的Webhook对象
    webhook = get_object_or_404(Webhook, id=webhook_id)
    
    # 验证项目标识是否匹配
    project = webhook.project
    expected_slug = str(project.id)


    if project_slug != expected_slug:
        return HttpResponseForbidden(_('项目标识不匹配'))
    
    # 验证请求方法
    if request.method != 'POST':
        return HttpResponseNotAllowed(['POST'])

    print(project_slug,webhook_id)
    
    try:
        # 获取请求数据
        if request.content_type == 'application/json':
            data = json.loads(request.body)
        else:
            data = dict(request.POST)
        
        # 验证签名（如果设置了secret）
        if webhook.secret:
            # 从请求头中获取签名
            signature_header = request.headers.get('X-Webhook-Signature')
            if not signature_header:
                return HttpResponseForbidden(_('缺少签名'))
            
            # 生成签名并验证
            import hmac, hashlib
            payload_str = json.dumps(data, separators=(',', ':'), ensure_ascii=False)
            signature = hmac.new(
                webhook.secret.encode('utf-8'),
                payload_str.encode('utf-8'),
                hashlib.sha256
            ).hexdigest()
            
            # 检查签名是否匹配
            if not hmac.compare_digest(f'sha256={signature}', signature_header):
                return HttpResponseForbidden(_('签名验证失败'))
        
        # 构建消息对象 - 使用中国时区的时间戳
        from django.utils import timezone
        # 获取当前时间并转换为中国时区
        china_time = timezone.now().astimezone(timezone.get_current_timezone())
        message = {
            'id': str(uuid.uuid4()),
            'timestamp': china_time.isoformat(),
            'data': data,
            'source': request.headers.get('User-Agent', 'unknown'),
            'ip': request.META.get('REMOTE_ADDR', 'unknown')
        }
        
        # 创建Message对象
        from .views import create_message_from_webhook
        create_message_from_webhook({
            'webhook_id': str(webhook.id),
            'webhook_name': webhook.name,
            'event': webhook.events,
            'channel': webhook.channel,
            'data': data,
            'source': request.headers.get('User-Agent', 'unknown'),
            'ip': request.META.get('REMOTE_ADDR', 'unknown'),
            'timestamp': china_time.isoformat()
        }, project)
        
        # 将消息添加到项目的webhook_messages字段中（保持向后兼容）
        project.webhook_messages.append(message)
        
        # 限制消息数量，只保留最近的100条消息
        if len(project.webhook_messages) > 100:
            project.webhook_messages = project.webhook_messages[-100:]
        
        # 保存项目
        project.save()
        
        # 更新webhook的最后触发时间
        webhook.last_triggered_at = timezone.now()
        webhook.save()
        
        # 返回成功响应
        return JsonResponse({
            'status': 'success',
            'message': 'Webhook消息已成功接收并存储'
        }, status=200)
        
    except json.JSONDecodeError:
        return JsonResponse({
            'status': 'error',
            'message': '无效的JSON数据'
        }, status=400)
    except Exception as e:
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f'处理Webhook请求时出错: {str(e)}')
        return JsonResponse({
            'status': 'error',
            'message': '处理请求时发生错误'
        }, status=500)


@csrf_exempt
def receive_webhook_alt(request, project_id, webhook_id):
    """接收Webhook请求的替代端点，直接使用项目ID而不是slug"""
    print(f"收到替代Webhook请求: project_id={project_id}, webhook_id={webhook_id}")
    
    # 验证项目是否存在
    try:
        project = Project.objects.get(id=project_id)
    except Project.DoesNotExist:
        return JsonResponse({'error': '项目不存在'}, status=404)
    
    # 验证Webhook是否存在
    try:
        webhook = Webhook.objects.get(id=webhook_id)
    except Webhook.DoesNotExist:
        return JsonResponse({'error': 'Webhook不存在'}, status=404)
    
    # 验证Webhook是否属于该项目
    if webhook.project.id != project_id:
        return JsonResponse({'error': 'Webhook不属于此项目'}, status=403)
    
    # 其余逻辑与receive_webhook相同
    try:
        # 获取请求数据
        if request.content_type == 'application/json':
            data = json.loads(request.body)
        else:
            data = dict(request.POST)
        
        # 验证签名（如果设置了secret）
        if webhook.secret:
            # 从请求头中获取签名
            signature_header = request.headers.get('X-Webhook-Signature')
            if not signature_header:
                return HttpResponseForbidden(_('缺少签名'))
            
            # 生成签名并验证
            import hmac, hashlib
            payload_str = json.dumps(data, separators=(',', ':'), ensure_ascii=False)
            signature = hmac.new(
                webhook.secret.encode('utf-8'),
                payload_str.encode('utf-8'),
                hashlib.sha256
            ).hexdigest()
            
            # 检查签名是否匹配
            if not hmac.compare_digest(f'sha256={signature}', signature_header):
                return HttpResponseForbidden(_('签名验证失败'))
        
        # 构建消息对象 - 使用中国时区的时间戳
        from django.utils import timezone
        # 获取当前时间并转换为中国时区
        china_time = timezone.now().astimezone(timezone.get_current_timezone())
        message = {
            'id': str(uuid.uuid4()),
            'timestamp': china_time.isoformat(),
            'data': data,
            'source': request.headers.get('User-Agent', 'unknown'),
            'ip': request.META.get('REMOTE_ADDR', 'unknown')
        }
        
        # 创建Message对象
        from .views import create_message_from_webhook
        create_message_from_webhook({
            'webhook_id': str(webhook.id),
            'webhook_name': webhook.name,
            'event': webhook.events,
            'channel': webhook.channel,
            'data': data,
            'source': request.headers.get('User-Agent', 'unknown'),
            'ip': request.META.get('REMOTE_ADDR', 'unknown'),
            'timestamp': china_time.isoformat()
        }, project)
        
        # 将消息添加到项目的webhook_messages字段中（保持向后兼容）
        project.webhook_messages.append(message)
        
        # 限制消息数量，只保留最近的100条消息
        if len(project.webhook_messages) > 100:
            project.webhook_messages = project.webhook_messages[-100:]
        
        # 保存项目
        project.save()
        
        # 更新webhook的最后触发时间
        webhook.last_triggered_at = timezone.now()
        webhook.save()
        
        # 返回成功响应
        return JsonResponse({
            'status': 'success',
            'message': 'Webhook消息已成功接收并存储'
        }, status=200)
        
    except json.JSONDecodeError:
        return JsonResponse({
            'status': 'error',
            'message': '无效的JSON数据'
        }, status=400)
    except Exception as e:
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f'处理Webhook请求时出错: {str(e)}')
        return JsonResponse({
            'status': 'error',
            'message': '处理请求时发生错误'
        }, status=500)


@csrf_exempt
def test_webhook(request, project_id, webhook_id):
    """简单的Webhook测试视图"""
    # 只允许GET请求
    if request.method != 'GET':
        return JsonResponse({
            'success': False,
            'error': '只允许GET请求'
        }, status=405)
        
    print(f"收到测试Webhook请求: project_id={project_id}, webhook_id={webhook_id}")
    
    # 验证项目是否存在
    try:
        project = Project.objects.get(id=project_id)
    except Project.DoesNotExist:
        return JsonResponse({'error': 'Project not found'}, status=404)
    
    # 验证Webhook是否存在
    try:
        webhook = Webhook.objects.get(id=webhook_id)
    except Webhook.DoesNotExist:
        return JsonResponse({'error': 'Webhook not found'}, status=404)
    
    # 验证Webhook是否属于该项目
    if webhook.project.id != project_id:
        return JsonResponse({'error': 'Webhook does not belong to this project'}, status=403)
    
    # 简单返回成功信息
    return JsonResponse({
        'success': True,
        'message': 'Webhook is working correctly',
        'project_id': project_id,
        'webhook_id': webhook_id,
        'webhook_name': webhook.name
    })


from django.contrib.admin.views.decorators import staff_member_required
from .models import Announcement
from .forms import AnnouncementForm

@staff_member_required
def announcement_list(request):
    """公告列表视图 - 仅管理员可访问"""
    announcements = Announcement.objects.all().order_by('-created_at')
    return render(request, 'projects/announcement_list.html', {
        'announcements': announcements
    })

@staff_member_required
def announcement_create(request):
    """创建公告视图 - 仅管理员可访问"""
    if request.method == 'POST':
        form = AnnouncementForm(request.POST)
        if form.is_valid():
            announcement = form.save(commit=False)
            announcement.created_by = request.user
            announcement.save()
            form.save_m2m()  # 保存多对多关系
            
            # 发送公告到相关项目
            send_announcement_to_projects(announcement)
            
            messages.success(request, _('公告创建成功并已发送！'))
            return redirect('projects:announcement_list')
    else:
        form = AnnouncementForm()
    
    return render(request, 'projects/announcement_form.html', {
        'form': form,
        'title': _('创建公告')
    })

@staff_member_required
def announcement_edit(request, announcement_id):
    """编辑公告视图 - 仅管理员可访问"""
    announcement = get_object_or_404(Announcement, id=announcement_id)
    
    if request.method == 'POST':
        form = AnnouncementForm(request.POST, instance=announcement)
        if form.is_valid():
            form.save()
            messages.success(request, _('公告更新成功！'))
            return redirect('projects:announcement_list')
    else:
        form = AnnouncementForm(instance=announcement)
    
    return render(request, 'projects/announcement_form.html', {
        'form': form,
        'title': _('编辑公告'),
        'announcement': announcement
    })

@staff_member_required
def announcement_delete(request, announcement_id):
    """删除公告视图 - 仅管理员可访问"""
    announcement = get_object_or_404(Announcement, id=announcement_id)
    
    if request.method == 'POST':
        announcement.delete()
        messages.success(request, _('公告删除成功！'))
        return redirect('projects:announcement_list')
    
    return render(request, 'projects/announcement_confirm_delete.html', {
        'announcement': announcement
    })

@login_required
def project_announcements(request, project_id):
    """项目公告列表视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以访问所有项目的公告
    if not request.user.is_super_admin() and not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取项目的所有标签
    project_tags = project.tags.all()
    
    # 获取与项目相关的公告
    announcements = Announcement.objects.filter(
        Q(tags__in=project_tags) | Q(tags__isnull=True) | Q(tags__count=0),
        is_active=True
    ).distinct().order_by('-created_at')
    
    return render(request, 'projects/project_announcements.html', {
        'project': project,
        'announcements': announcements
    })

def send_announcement_to_projects(announcement):
    """将公告发送到相关项目"""
    # 触发公告事件（用于webhook通知和消息创建）
    trigger_announcement_sent(announcement)


@login_required
def message_list(request, project_id):
    """消息列表视图"""
    project = get_object_or_404(Project, id=project_id)
    
    # 超级管理员可以访问所有项目的消息
    if not request.user.is_super_admin() and not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取消息类型筛选参数
    message_type = request.GET.get('type', '')
    status = request.GET.get('status', '')
    
    # 基础查询集
    messages = Message.objects.filter(project=project)
    
    # 应用筛选条件
    if message_type:
        messages = messages.filter(message_type=message_type)
    if status:
        messages = messages.filter(status=status)
    
    # 排序
    messages = messages.order_by('-created_at')
    
    # 分页
    paginator = Paginator(messages, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 计算统计数据
    all_messages = Message.objects.filter(project=project)
    pending_count = all_messages.filter(status='pending').count()
    processed_count = all_messages.filter(status='processed').count()
    webhook_count = all_messages.filter(message_type='webhook').count()
    
    return render(request, 'projects/message_list.html', {
        'project': project,
        'page_obj': page_obj,
        'message_type': message_type,
        'status': status,
        'pending_count': pending_count,
        'processed_count': processed_count,
        'webhook_count': webhook_count,
    })


@login_required
def message_detail(request, project_id, message_id):
    """消息详情视图"""
    project = get_object_or_404(Project, id=project_id)
    message = get_object_or_404(Message, id=message_id, project=project)
    
    # 超级管理员可以访问所有项目的消息详情
    if not request.user.is_super_admin() and not project.members.filter(user=request.user).exists():
        return HttpResponseForbidden(_('您没有权限访问此项目。'))
    
    # 获取处理历史记录
    processing_history = message.processing_history.all().order_by('-performed_at')
    
    # 获取备注信息
    notes = message.notes.all().order_by('-created_at')
    
    # 处理添加备注的表单提交
    if request.method == 'POST' and request.POST.get('action') == 'add_note':
        note_content = request.POST.get('note_content', '').strip()
        if note_content:
            MessageNote.objects.create(
                message=message,
                content=note_content,
                author=request.user
            )
            # 同时创建处理历史记录
            MessageProcessingHistory.objects.create(
                message=message,
                action='note_added',
                performed_by=request.user,
                notes=note_content
            )
            messages.success(request, _('备注添加成功！'))
            return redirect('projects:message_detail', project_id=project.id, message_id=message.id)
    
    return render(request, 'projects/message_detail.html', {
        'project': project,
        'message': message,
        'processing_history': processing_history,
        'notes': notes,
    })


@login_required
def message_toggle_status(request, project_id, message_id):
    """切换消息状态视图"""
    # 处理GET请求 - 返回405错误但提供更友好的信息
    if request.method == 'GET':
        return JsonResponse({
            'success': False,
            'message': _('此操作只能通过POST请求执行，请使用正确的表单提交方式')
        }, status=405)
    
    # 只允许POST请求
    if request.method != 'POST':
        return JsonResponse({
            'success': False,
            'message': _('只允许POST请求')
        }, status=405)
        
    project = get_object_or_404(Project, id=project_id)
    message = get_object_or_404(Message, id=message_id, project=project)
    
    # 检查用户权限：所有项目成员都可以标记为已处理，只有管理员可以撤销为未处理
    has_permission = False
    is_admin = False
    
    if request.user.is_super_admin():
        has_permission = True
        is_admin = True
    else:
        try:
            member = project.members.get(user=request.user)
            has_permission = True
            if member.role == 'admin':
                is_admin = True
        except ProjectMember.DoesNotExist:
            pass
    
    if not has_permission:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                'success': False,
                'message': _('您没有权限修改此消息。')
            }, status=403)
        else:
            messages.error(request, _('您没有权限修改此消息。'))
            return redirect('projects:dashboard')
    
    # 处理表单提交
    if request.content_type == 'application/json':
        try:
            data = json.loads(request.body)
            action = data.get('action')
            
            if action == 'mark_processed':
                message.mark_as_processed(request.user)
                message_text = _('已标记为已处理')
            elif action == 'mark_pending':
                # 只允许管理员将消息标记为未处理
                if not is_admin:
                    return JsonResponse({
                        'success': False,
                        'message': _('您没有权限将消息标记为未处理，只有管理员可以执行此操作。')
                    }, status=403)
                message.mark_as_pending(request.user)
                message_text = _('已标记为未处理')
            else:
                return JsonResponse({
                    'success': False,
                    'message': _('无效的操作')
                }, status=400)
            
            return JsonResponse({
                'success': True,
                'message': message_text,
                'status': message.status,
                'processed_by': message.processed_by.username if message.processed_by else None,
                'processed_at': message.processed_at.isoformat() if message.processed_at else None
            })
            
        except json.JSONDecodeError:
            return JsonResponse({
                'success': False,
                'message': _('无效的请求数据')
            }, status=400)
    else:
        # 处理表单提交
        message.mark_as_processed(request.user)
        messages.success(request, _('消息已成功标记为已处理！'))
        return redirect('projects:dashboard')


@login_required
def message_bulk_update(request, project_id):
    """批量更新消息状态"""
    project = get_object_or_404(Project, id=project_id)
    
    # 检查用户权限：所有项目成员都可以批量标记为已处理，只有管理员可以批量撤销为未处理
    has_permission = False
    is_admin = False
    
    if request.user.is_super_admin():
        has_permission = True
        is_admin = True
    else:
        try:
            member = project.members.get(user=request.user)
            has_permission = True
            if member.role == 'admin':
                is_admin = True
        except ProjectMember.DoesNotExist:
            pass
    
    if not has_permission:
        return JsonResponse({
            'success': False,
            'message': _('您没有权限执行此操作。')
        }, status=403)
    
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            message_ids = data.get('message_ids', [])
            action = data.get('action')
            
            if not message_ids or not action:
                return JsonResponse({
                    'success': False,
                    'message': _('缺少必要参数')
                }, status=400)
            
            messages = Message.objects.filter(
                id__in=message_ids,
                project=project
            )
            
            updated_count = 0
            for message in messages:
                if action == 'mark_processed':
                    message.mark_as_processed(request.user)
                    updated_count += 1
                elif action == 'mark_pending':
                    # 只允许管理员批量将消息标记为未处理
                    if not is_admin:
                        return JsonResponse({
                            'success': False,
                            'message': _('您没有权限批量将消息标记为未处理，只有管理员可以执行此操作。')
                        }, status=403)
                    message.mark_as_pending(request.user)
                    updated_count += 1
            
            return JsonResponse({
                'success': True,
                'message': f'成功更新了 {updated_count} 条消息',
                'updated_count': updated_count
            })
            
        except json.JSONDecodeError:
            return JsonResponse({
                'success': False,
                'message': _('无效的请求数据')
            }, status=400)
    
    return JsonResponse({
        'success': False,
        'message': _('只支持POST请求')
    }, status=405)


def create_message_from_announcement(announcement, project):
    """从公告创建消息"""
    message = Message.objects.create(
        project=project,
        message_type='announcement',
        title=announcement.title,
        content=announcement.content,
        source_data={
            'announcement_id': str(announcement.id),
            'created_by': announcement.created_by.username,
            'tags': [tag.name for tag in announcement.tags.all()]
        }
    )
    return message


def create_message_from_webhook(webhook_data, project):
    """从webhook数据创建消息"""
    title = webhook_data.get('title', 'Webhook消息')
    content = webhook_data.get('content', str(webhook_data.get('data', {})))
    
    message = Message.objects.create(
        project=project,
        message_type='webhook',
        title=title,
        content=content,
        source_data=webhook_data
    )
    return message


def trigger_announcement_sent(announcement):
    """公告发送事件触发器"""
    # 获取公告关联的标签
    target_tags = announcement.tags.all()
    
    # 根据标签筛选项目
    if target_tags:
        projects = Project.objects.filter(tags__in=target_tags).distinct()
    else:
        projects = Project.objects.all()
    
    # 为每个项目创建消息
    for project in projects:
        create_message_from_announcement(announcement, project)


def trigger_webhook_message_received(webhook_data, project):
    """webhook消息接收事件触发器"""
    create_message_from_webhook(webhook_data, project)


def webhook_urls(request):
    """展示所有webhook URL的完整列表页面（无需登录）"""
    webhooks = Webhook.objects.select_related('project').all()
    
    context = {
        'webhooks': webhooks,
        'total_count': webhooks.count(),
        'active_count': webhooks.filter(is_active=True).count(),
        'project_count': webhooks.values('project').distinct().count()
    }
    return render(request, 'projects/webhook_urls.html', context)


def api_webhooks(request):
    """API端点：获取所有webhook数据（无需登录）"""
    webhooks = Webhook.objects.select_related('project').all()
    
    data = []
    for webhook in webhooks:
        data.append({
            'id': str(webhook.id),
            'name': webhook.name,
            'project': {
                'id': webhook.project.id,
                'name': webhook.project.name,
                'slug': str(webhook.project.id)
            },
            'url': f"http://{request.get_host()}/webhooks/{webhook.project.id}/{webhook.id}/receive/",
            'alt_url': f"http://{request.get_host()}/webhooks/{webhook.project.id}/{webhook.id}/receive/",
            'channel': webhook.get_channel_display(),
            'channel_value': webhook.channel,
            'events': webhook.events,
            'is_active': webhook.is_active,
            'created_at': webhook.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'last_triggered_at': webhook.last_triggered_at.strftime('%Y-%m-%d %H:%M:%S') if webhook.last_triggered_at else None,
            'trigger_count': 0,
            'status': '激活' if webhook.is_active else '禁用'
        })
    
    return JsonResponse({'webhooks': data, 'count': len(data)})
